/*! \file component.h	
	This is the header file for component.cpp
	
	This contains the Component class
*/

#ifndef COMPONENT_H
#define COMPONENT_H

#include <vector>

#include "guiconstants.h"
#include "image.h"
using namespace std;

class Listener;

/**
	\class Component

	This is the super GUI class from which every GUI element derives.

	You cannot make a component directly.
*/

class Component {
protected:
	/** The parent component */
	Component* parent;


	/** \brief x-coordinate
	*
	* This will be relative to the parent, unless the parent
	* is the main GUI, in which case it will be relative to the screen (so just 0)
	*/
	int x;

	/** \brief y-coordinate
	*
	* See \link #x x for information \endlink
	*/
	int y;

	int w; //!< width
	int h; //!< height

	int id; //!< unique id

	Color bgColorTop; //!< Top of the background gradient
	Color bgColorBottom; //!< Bottom of the background gradient

	vector<Listener*> listeners; //!< List of listeners this component has
	
	/**
	* This is true when the mouse is over the component
	*/
	bool mouseIsOver;
	
	/**
	* This is true when the mouse was clicked over a component (it's made false on release)
	*/
	bool mouseIsDown;
	
	/**
	* If a component is not visible, then none of its children will be drawn, and
	* nothing will work on it until it is made visible.
	*/
	bool visible;
	
	bool border;
	
	// The comments about focus are not completely true... just try it out
	// when this has the focus, use this style
	int sideID1; 
	int cornerID1;
	// This is the width of the sideID1 image
	int borderWidth;
	// when it doesn't have the focus, use this style
	int sideID2;
	int cornerID2;
public:
	/**	
	* 	Adds a listener
	*/
	void addListener( Listener* l );


	/**
	* Constructor
	*/
	Component( Component* parent );
	//~ virtual ~Component();

	/**
	* Set whether this component has a border around it
	* \param enabled true if it has a border
	*/
	void setBorder( bool enabled );

	/**
	* draw
	*/
	virtual void draw() = 0;

	/**
	* update - mostly unused
	*/
	virtual void update() = 0;
	
	/**
	* This changes the style (of just the border for now)
	* \param unfocusedSideID	The image index of the side of the border when this doesn't have the focus
	* \param unfocusedCornerID	The image index of the corner of the border when this doesn't have the focus
	* \param focusedSideID		The image index of the side of the border when this has the focus
	* \param focusedCornerID	The image index of the corner of the border when this has the focus
	*/
	void setGUIStyle( int unfocusedSideID, int unfocusedCornerID, int focusedSideID, int focusedCornerID );
	
	void setDefaultGUIStyle();
	
	/**
	* This returns true if this component can get the focus.
	* StaticText wouldn't ever need the focus, so it will overwrite this
	* with a return false;
	*/
	virtual bool canHaveFocus();
	
	
	
	virtual bool handleMouseWheel( int pos );
	
	/** 
	* Each component will have a handle___ class, like handleMouse. If the conditions are true
	* for whatever component, then it will propagate the event down to its children.
	* \param mX the mouse X value
	* \param mY the mouse Y value
	*/
	virtual bool handleMouseMove( int mX, int mY );
	
	virtual void sendMouseUpEvent();
	
	virtual void sendOnLeaveEvent();

	/** 
	* Handles mouse clicks
	* \param button the mouse button pressed
	* \param state either pressed or released
	*/
	virtual bool handleMouseClick( int button, int state );
	
	/** 
	* Handles keyboard input
	* \param key the key pressed
	* \param state either pressed or released
	*/
	virtual void handleKeyInput( int key, int state );
	
	
	/**
	* This sets the size of the component. These are virtual because text components
	* will overwrite them. This is just a simple mutator, but the text components
	* need to base the size off of other values.
	* \param newWidth the new width
	* \param newHeight the new height
	*/
	virtual void setSize( int newWidth, int newHeight );
	
	/**
	* Change this component's visibility
	* \param visibility true if visible
	*/
	virtual void setVisible( bool visibility );
	
	/**
	* Returns true if this component is visible
	*/
	virtual bool isVisible();
	
	/**
	* This returns the type of the component. This is probably unused.
	* These are defined in \link guiconstants.h \endlink
	*/
	virtual int getType();
	
public:
	virtual void setWidth( int newWidth ); //!< basic mutator
	virtual void setHeight( int newHeight ); //!< basic mutator
	int getX(); //!< basic accessor, this gets the X relative to the parent
	int getY(); //!< basic accessor, this gets the Y relative to the parent
	int getScreenX(); //!< this gets the X relative to the left side of the screen
	int getScreenY(); //!< this gets the Y relative to the top of the screen
	void setID( int ID ); //!< basic mutator
	int getID(); //!< basic accessor
	void setX( int newX );
	void setY( int newY );
	void setBackgroundColor( Color top, Color bottom );
	int getWidth();
	int getBorderWidth();
	int getHeight();
	void setPosition( int newX, int newY ); //!< basic mutator
	Component* getParent() { return parent; }
};


#endif
